#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#	   bp_imdb.py
#	   
#	   Copyright 2012 Bruno Paulin <brunopaulin@bpaulin.net>
#	   
#	   This program is free software; you can redistribute it and/or modify
#	   it under the terms of the GNU General Public License as published by
#	   the Free Software Foundation; either version 2 of the License, or
#	   (at your option) any later version.
#	   
#	   This program is distributed in the hope that it will be useful,
#	   but WITHOUT ANY WARRANTY; without even the implied warranty of
#	   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	   GNU General Public License for more details.
#	   
#	   You should have received a copy of the GNU General Public License
#	   along with this program; if not, write to the Free Software
#	   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#	   MA 02110-1301, USA.
#	   
#	   
import getopt
import sys
import os
import glob
import re
import imdb


#### SETTINGS
# filename extensions to rename
ext_movies = ('.avi','.mkv')
# words used to split the file name to guess the movie title
seps = ('dvdrip', 'truefrench', 'french')
# sounds
sounds = ('VO', 'VF', 'VOSTFR')
# Forbidden character
forbiddens = '\/:*?"<>|'
replacement = '_'
## SETTINGS


#### Help message
def Help(problem):
	print """
bp-imdb comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.

bp_imdb is a file renamer using Imdb

Usage: bp_imdb [OPTION] SRC [DEST]

Options
-b --batch		Always choose the first choice (can be dangerous)
-s --sim		Print what would be done, but don't do anything
-h --help		Print this message
"""
	sys.exit(problem)
## Help message


#### rename
def Rename(old_file, new_name, new_dest, sim):
	# Clean the name a little
	for forbidden in forbiddens:
		new_name = new_name.replace(forbidden, replacement)
	# New path
	new_file = os.path.join(new_dest, new_name + os.path.splitext(old_file)[1])
	# print summary
	print('## %s'%os.path.basename(old_file))
	print('-> %s'%os.path.basename(new_file))
	# rename
	if not sim:
		os.renames(old_file, new_file)
## Rename

#### run
def main():
	## Loading config
	try:
		# Filter options and aguments
		opts, args = getopt.getopt(sys.argv[1:], "bsh", ["batch", "sim", "help"])
	except getopt.GetoptError, err:
		# Unknow options
		print str(err)
		Help(1)
	else:
		batch = False
		sim = False
		# Manage Options
		for o, a in opts:
			if o in ("-h", "--help"):
				Help(0)
			elif o in ("-b", "--batch"):
				batch = True
			elif o in ("-s", "--sim"):
				sim = True
	# Src directory
	src = ''
	try:
		src = args[0]
	except:
		src = os.getcwd()
	# Dest directory
	dest = ''
	try:
		dest = args[1]
	except:
		dest = src
		
	## Print config summary
	if batch:
		print('Batch mode activated')
	if sim:
		print('sim mode activated')
	print('source: %s'%src)
	print('destination: %s'%dest)
	
	## Files list
	movie_files = []
	# if src is a dir
	if os.path.isdir(src):
		# add all files in this dir and sub-dir
		movie_files=[] 
		for root, dirs, files in os.walk(src): 
			for i in files: 
				movie_files.append(os.path.join(root, i))
	# if src is a file
	else:
		# add this file
		movie_files = (src,)
	# keep only files with movies extensions
	movie_files = [file_name for file_name in movie_files 
					if (os.path.splitext(file_name)[1] in ext_movies)]
	movie_files.sort()
	nb_files = len(movie_files)
	print('%i file(s) found'%nb_files)
	
	imdb_engine = imdb.IMDb()
	## For each file
	for movie_file in movie_files:
		## guess keyword
		# from filename
		keyword = os.path.splitext(os.path.basename(movie_file))[0].lower()
		# split with separators
		for sep in seps:
			keyword = keyword.split(sep)[0]
		# split with year (XXXX) and keep only the 1st part
		keyword = re.split('[0-9]{4}',keyword)[0]
		# a little cleaning
		keyword = keyword.replace('.', ' ')
		keyword = keyword.replace('(', ' ')
		keyword = keyword.replace('[', ' ')
		keyword = keyword.strip()
		
		## Find movie
		while True:
			# init
			ignore = False
			found = False
			# print summary
			print('################################################')
			print("## file: %s"%os.path.splitext(os.path.basename(movie_file))[0])
			print('## keyword: %s'%keyword)
			
			## Search imdb
			result_list = imdb_engine.search_movie(keyword)
			
			## Batch mode
			if batch:
				# if any result
				if (len(result_list)>0):
					# select the first movie
					movie = result_list[0]
					found = True
				else:
					# Ignore this file
					ignore = True
					
			## Manual mode
			else:
				## Ask for a choice
				print("   (0) don't rename this file")
				for index, result in enumerate(result_list[:5]):
					print "   (%i) %s"%(index+1, result['long imdb title'])
				print("   (anything else) new keyword for a new search")
				choice = raw_input('   ? ')
				
				## User want to abort for this file
				if choice=='0':
					ignore = True
				else:
					## User has selected a valid movie number
					try:
						int_choice = int(choice)
						movie = result_list[int_choice-1]
						found = True
					## User want to search with a new keyword
					except:
						keyword = choice
						print('## new search')
			
			## Abort for this file
			if ignore:
				print('## nothing done, next movie')
				break
			## Movie found
			elif found:
				print('## movie found: %s'%movie['long imdb title'])
				break
		
		## Try to find others files from the same movie
		same_movie_files = []
		if movie_file.lower().count('cd1')>0:
			movie_file_wo_cd = os.path.splitext(os.path.basename(movie_file.lower().replace('cd1','')))[0]
			movie_files2  = movie_files 
			same_movie_files = [f for f in movie_files2
								if f.lower().count(movie_file_wo_cd)>0]	
		
		## Movie found
		if found:
			
			## Ask version
			sound = ''
			if not batch and len(sounds)>0:
				for index, sound in enumerate(sounds):
					print("  (%i) %s"%(index+1, sound))
				print("  (anything else) don't choose a version")
				choice = raw_input('   ? ')
				try:
					sound = ' '+sounds[int(choice)-1]
				except:
					sound = ''
			
			## build new name
			new_name = '%s (%s)%s'%(movie['title'], movie['year'], sound)
			
			##renaming
			if len(same_movie_files)>0:
				## multi files movie
				for index, same_movie_file in enumerate(same_movie_files):
					Rename(same_movie_file, new_name + ' cd%i'%(index+1), dest, sim)

			else:
				## one file movie
				Rename(movie_file, new_name, dest, sim)

		## removing others files of this movie from main movie list
		for same_movie_file in same_movie_files[1:]:
			movie_files.remove(same_movie_file)
			if ignore:
				print('## ignored:%s'%os.path.basename(same_movie_file))
## run
	
if __name__ == '__main__':
	main()

